﻿module Utils
open Types
open System.Drawing
open System.Windows.Forms
open MathNet.Numerics
open MathNet.Numerics.FSharp
open MathNet.Numerics.LinearAlgebra.Double
open System
open System.Collections.Generic
open Microsoft.Office.Interop.Excel

let seed = Random()

let ones n =
    let out = DenseMatrix(n,1)
    for i = 1 to n do
      out.[i - 1,0] <- 1.0
    out
  
let sum_column (a:DenseMatrix) =
  let out = DenseMatrix(1,a.ColumnCount)
  for j = 1 to a.ColumnCount do
    let mutable sum = 0.0
    for i = 1 to a.RowCount do
      sum <- sum + a.[i - 1,j - 1]
    out.[0,j - 1] <- sum
  out

let matrix_square (a:DenseMatrix) =
  let out = DenseMatrix(a.RowCount,a.ColumnCount)
  for i = 1 to a.RowCount do
    for j = 1 to a.ColumnCount do
      out.[i - 1,j - 1] <- a.[i - 1,j - 1] * a.[i - 1, j - 1]
  out

let plot_with_data (data : DenseMatrix) (data_color : List<DenseVectorWrapper>) (error : DenseVector) =

  let error_data = Array2D.init error.Count 2 (fun i j ->if j = 0 then (i + 1) |> float else error.[i])
  let component_data = Array2D.init data.RowCount 2 (fun i j -> data.[i,j])
  let component_color = Array2D.init data.RowCount 1 (fun i j -> data_color.[i].RealNumber )

  try
    // Run Excel as a visible application
    let app = new ApplicationClass(Visible = true) 

    // Create new file and get the first worksheet
    let workbook = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet) 
    // Note that worksheets are indexed from one instead of zero
    let worksheet = (workbook.Worksheets.[1] :?> Worksheet)

    // Store data in arrays of strings or floats
    


    // Populate data into Excel worksheet
    worksheet.Range("A1", "B256").Value2 <- error_data
    worksheet.Range("C1","C" + (data_color.Count).ToString()).Value2 <- component_color
    worksheet.Range("D1","E" + (data.RowCount).ToString()).Value2 <- component_data
  with
  |_ -> 
    let mutable string_to_print = ""
    for i in 0 .. error.Count - 1 do
      string_to_print <- string_to_print + (string error_data.[1,i] + "\n")
    
    for i in 0 .. data.RowCount - 1 do          
      string_to_print <- string_to_print + (string data.[i,0] + ";" + 
                                            string data.[i,1] + ";" + 
                                            string data_color.[i] + "\n")
    System.IO.File.WriteAllText("..\results_test.data", string_to_print)

let plot (error : DenseVector) =
  try

    // Run Excel as a visible application
    let app = new ApplicationClass(Visible = true) 

    // Create new file and get the first worksheet
    let workbook = app.Workbooks.Add(XlWBATemplate.xlWBATWorksheet) 
    // Note that worksheets are indexed from one instead of zero
    let worksheet = (workbook.Worksheets.[1] :?> Worksheet)

    // Store data in arrays of strings or floats
    let rnd = new Random()
    let error_data = Array2D.init error.Count 2 (fun i j ->if j = 0 then (i + 1) |> float else error.[i])

    // Populate data into Excel worksheet
    worksheet.Range("A1", "B256").Value2 <- error_data
  with
  |_ -> 
    let mutable string_to_print = ""
    for i in 0 .. error.Count - 1 do
      string_to_print <- string_to_print + (string error.[i] + "\n")
    System.IO.File.WriteAllText("..\results_test.data", string_to_print)  

//X column and C column must be the same
let concat_matrix (x : DenseMatrix) (c : DenseMatrix) =  
  let out = DenseMatrix(x.RowCount + c.RowCount, x.ColumnCount)
  for i = 0 to out.RowCount - 1 do
    let row_to_add = 
      if i < x.RowCount then
        x.Row i
      else 
        c.Row (i - x.RowCount)
    out.SetRow(i, row_to_add)
  out
  